#pragma once 

#include<iostream>
#include<string>
#include<vector>
#include<cstring>
#include"Util.hpp"
#include "jsoncpp/json/json.h"



#define SEP " "
#define SEP_LEN strlen(SEP)
#define HEADER_SEP "\r\n"
#define HEADER_SEP_LEN strlen(HEADER_SEP)

//条件编译
//#define MYSELF 1

namespace ns_protocol
{
    //添加报头
    std::string AddHeader(const std::string str)
    {
        std::string out;
        out=std::to_string(str.size());
        out+=HEADER_SEP;
        out+=str;
        out+=HEADER_SEP;

        //std::cout<<out<<std::endl;

        return out;
    }    

    //去除报头
    //"7"\r\n"10 + 20"\r\n => "10 + 20"
    std::string RemoveHeader(const std::string str,int len)
    {
        return str.substr(str.size()-HEADER_SEP_LEN-len,len);
    }   

    //读取数据
    //返回值：-1表述读取异常；0表示读取数据不全；非0为读取数据长度
    //读取到："7"\r\n"10 + 20"\r\n   报文 = 报头+有效载荷
    int ReadPackage(int sock,std::string&inBuffer,std::string*package)
    {
        char buffer[1024];
        int n=recv(sock,buffer,sizeof(buffer)-1,0);
        
        if(n<=0) 
            return -1;//读取异常或者客户端退出
        else
        {
            buffer[n]=0;
            inBuffer+=buffer;//添加数据

            // 1.提取报头
            size_t pos=inBuffer.find(HEADER_SEP,0);
            if(pos==std::string::npos) 
                return 0;//没有完整数据

            // 2.获取报文长度
            std::string len_string=inBuffer.substr(0,pos);
            int len=Util::ToInt(len_string);//获取有效载荷的长度
            //std::cout<<"有效载荷长度"<<len<<std::endl;
            
            int targetStringLen=len_string.size()+len+HEADER_SEP_LEN*2;//报文的长度
            //std::cout<<"报文长度"<<targetStringLen<<std::endl;

            if(inBuffer.size()<targetStringLen)
                return 0;//没有完整数据
            
            // 3.提取报文
            *package=inBuffer.substr(0,targetStringLen);
            //std::cout<<"报文"<<*package<<std::endl;

            // 4.将提取的报文从缓冲区删除
            inBuffer.erase(inBuffer.begin(),inBuffer.begin()+targetStringLen);
            return len;
        }
    }

    class Resquest
    {
    public:
        Resquest(){}
        Resquest(int x,int y,char op)
        :_x(x),_y(y),_op(op)
        {}

        //序列化：struct -> string
        //"10 + 20"
        bool Serialize(std::string* outStr)
        {
            *outStr="";

#ifdef MYSELF        
            std::string x_string = std::to_string(_x);
            std::string y_string = std::to_string(_y);

            *outStr=x_string + SEP + _op + SEP + y_string;
#else
            Json::Value root;//万能对象，接收任意的kv模型
            root["x"]=_x;
            root["y"]=_y;
            root["op"]=_op;

            //序列化
            Json::FastWriter writer;
            *outStr=writer.write(root);
#endif
            return true;
        }

        //反序列化：string -> struct
        bool Deserialize(const std::string&inStr)
        {
#ifdef MYSELF
            //将inStr截取成一个个字符串，放入vector中
            std::vector<std::string>res;
            Util::StrSplit(inStr,SEP,res);
            if(res.size()!=3) return false;
            if(res[1].size()!=1) return false;

            _x=Util::ToInt(res[0]);
            _y=Util::ToInt(res[2]);
            _op=res[1][0];
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(inStr,root);
            _x=root["x"].asInt();
            _y=root["y"].asInt();
            _op=root["op"].asInt();
#endif
            return true;
        }
         
    public:
        int _x;
        int _y;
        char _op;
    };

    class Responce
    {
    public:
        Responce(){}
        Responce(int result,int code)
        :_result(result),_code(code)
        {}

        //序列化：struct -> string
        //"_result _code"
        bool Serialize(std::string* outStr)
        {
            *outStr="";
#ifdef MYSELF
            std::string res_str=std::to_string(_result);
            std::string code_str=std::to_string(_code);

            *outStr=res_str + SEP + code_str;
#else
            Json::Value root;
            root["result"]=_result;
            root["code"]=_code;
            Json::FastWriter writer;
            *outStr=writer.write(root);
#endif
            return true;
        }

        //反序列化：string -> struct
        bool Deserialize(const std::string&inStr)
        {
#ifdef MYSELF
            //将inStr截取成一个个字符串，放入vector中
            std::vector<std::string>res;
            Util::StrSplit(inStr,SEP,res);
            if(res.size()!=2) return false;

            _result=Util::ToInt(res[0]);
            _code=Util::ToInt(res[1]);
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(inStr,root);
            _result=root["result"].asInt();
            _code=root["code"].asInt();
#endif

            return true;


        }
         
    public:
        int _result;
        int _code;
    };
}